import type { Context } from 'elysia';
import { eq } from 'drizzle-orm';
import { db } from '../db';
import { settings } from '../db/schema';
import fs from 'fs/promises';
import path from 'path';
import { spawn } from 'child_process';
import { successResponse, errorResponse, ApiError, asyncHandler, Logger } from '../utils/response';
import { checkReadOnlyAccess } from '../middleware/auth';

/**
 * 获取所有设置
 */
export const getSettings = asyncHandler(async ({ }: Context) => {
  const allSettings = await db.select().from(settings);
  
  // 转换为键值对格式
  const settingsMap: Record<string, any> = {};
  allSettings.forEach(setting => {
    try {
      settingsMap[setting.key] = JSON.parse(setting.value);
    } catch {
      settingsMap[setting.key] = setting.value;
    }
  });
  
  Logger.info('Settings retrieved', { count: allSettings.length });
  return successResponse(settingsMap);
});

/**
 * 获取单个设置
 */
export const getSetting = asyncHandler(async ({ params }: Context) => {
  const { key } = params as { key: string };
  
  const setting = await db.select()
    .from(settings)
    .where(eq(settings.key, key))
    .limit(1);
  
  if (setting.length === 0) {
    throw ApiError.notFound('设置项不存在');
  }
  
  let value;
  try {
    value = JSON.parse(setting[0]?.value || '{}');
  } catch {
    value = setting[0]?.value || '';
  }
  
  Logger.info('Setting retrieved', { key });
  return successResponse({
    key: setting[0]?.key || '',
    value,
    description: setting[0]?.description || '',
    updatedAt: setting[0]?.updatedAt || ''
  });
});

/**
 * 更新设置
 */
export const updateSetting = asyncHandler(async ({ params, body, user }: Context) => {
  // 检查权限
  const accessCheck = checkReadOnlyAccess(user, 'PUT');
  if (!accessCheck.allowed) {
    throw ApiError.forbidden(accessCheck.message);
  }
  const { key } = params as { key: string };
  const { value, description } = body as { value: any; description?: string };
  
  if (!key) {
    throw ApiError.validation('设置键不能为空');
  }
  
  // 将值转换为字符串存储
  const valueStr = typeof value === 'string' ? value : JSON.stringify(value);
  
  // 检查设置是否存在
  const existingSetting = await db.select()
    .from(settings)
    .where(eq(settings.key, key))
    .limit(1);
  
  if (existingSetting.length === 0) {
    // 创建新设置
    await db.insert(settings).values({
      key,
      value: valueStr,
      description: description || ''
    });
    Logger.info('Setting created', { key });
  } else {
    // 更新现有设置
    await db.update(settings)
      .set({
        value: valueStr,
        description: description || existingSetting[0]?.description || ''
      })
      .where(eq(settings.key, key));
    Logger.info('Setting updated', { key });
  }
  
  return successResponse(null, '设置更新成功');
});

/**
 * 批量更新设置
 */
export const updateSettings = asyncHandler(async ({ body, user }: Context) => {
  // 检查权限
  const accessCheck = checkReadOnlyAccess(user, 'PUT');
  if (!accessCheck.allowed) {
    throw ApiError.forbidden(accessCheck.message);
  }
  const settingsData = body as Record<string, any>;
  
  if (!settingsData || Object.keys(settingsData).length === 0) {
    throw ApiError.validation('设置数据不能为空');
  }
  
  // 批量更新设置
  const promises = Object.entries(settingsData).map(async ([key, data]) => {
    const { value, description } = data;
    const valueStr = typeof value === 'string' ? value : JSON.stringify(value);
    
    // 检查设置是否存在
    const existingSetting = await db.select()
      .from(settings)
      .where(eq(settings.key, key))
      .limit(1);
    
    if (existingSetting.length === 0) {
      // 创建新设置
      return db.insert(settings).values({
        key,
        value: valueStr,
        description: description || ''
      });
    } else {
      // 更新现有设置
      return db.update(settings)
        .set({
          value: valueStr,
          description: description || existingSetting[0]?.description || ''
        })
        .where(eq(settings.key, key));
    }
  });
  
  await Promise.all(promises);
  
  Logger.info('Settings batch updated', { count: Object.keys(settingsData).length });
  return successResponse(null, '设置批量更新成功');
});

/**
 * 获取产品标签
 */
export const getProductTags = asyncHandler(async ({ }: Context) => {
  const setting = await db.select()
    .from(settings)
    .where(eq(settings.key, 'product_tags'))
    .limit(1);
  
  let tags = [];
  if (setting.length > 0) {
    try {
      tags = JSON.parse(setting[0]?.value || '[]');
    } catch {
      tags = [];
    }
  }
  
  Logger.info('Product tags retrieved', { count: tags.length });
  return successResponse(tags);
});

/**
 * 更新产品标签
 */
export const updateProductTags = asyncHandler(async ({ body, user }: Context) => {
  // 检查权限
  const accessCheck = checkReadOnlyAccess(user, 'PUT');
  if (!accessCheck.allowed) {
    throw ApiError.forbidden(accessCheck.message);
  }
  const { tags } = body as { tags: string[] };
  
  if (!Array.isArray(tags)) {
    throw ApiError.validation('标签必须是数组格式');
  }
  
  const valueStr = JSON.stringify(tags);
  
  // 检查设置是否存在
  const existingSetting = await db.select()
    .from(settings)
    .where(eq(settings.key, 'product_tags'))
    .limit(1);
  
  if (existingSetting.length === 0) {
    await db.insert(settings).values({
      key: 'product_tags',
      value: valueStr,
      description: '产品标签列表'
    });
  } else {
    await db.update(settings)
      .set({
        value: valueStr
      })
      .where(eq(settings.key, 'product_tags'));
  }
  
  Logger.info('Product tags updated', { count: tags.length });
  return successResponse(null, '产品标签更新成功');
});

/**
 * 获取产品分类（一级分类）
 */
export const getProductCategories = asyncHandler(async ({ }: Context) => {
  const setting = await db.select()
    .from(settings)
    .where(eq(settings.key, 'product_categories'))
    .limit(1);
  
  let categories = [];
  if (setting.length > 0) {
    try {
      categories = JSON.parse(setting[0]?.value || '[]');
    } catch {
      categories = [];
    }
  }
  
  // 如果没有分类数据，返回默认分类
  if (categories.length === 0) {
    categories = ['门店招牌', '户外广告', '标识标牌', '室内装饰'];
  }
  
  Logger.info('Product categories retrieved', { count: categories.length });
  return successResponse(categories);
});

/**
 * 更新产品分类（一级分类）
 */
export const updateProductCategories = asyncHandler(async ({ body, user }: Context) => {
  // 检查权限
  const accessCheck = checkReadOnlyAccess(user, 'PUT');
  if (!accessCheck.allowed) {
    throw ApiError.forbidden(accessCheck.message);
  }
  const { categories } = body as { categories: string[] };
  
  if (!Array.isArray(categories)) {
    throw ApiError.validation('分类必须是数组格式');
  }
  
  // 验证分类名称
  for (const category of categories) {
    if (typeof category !== 'string' || !category.trim()) {
      throw ApiError.validation('分类名称必须是非空字符串');
    }
  }
  
  const valueStr = JSON.stringify(categories);
  
  // 检查设置是否存在
  const existingSetting = await db.select()
    .from(settings)
    .where(eq(settings.key, 'product_categories'))
    .limit(1);
  
  if (existingSetting.length === 0) {
    await db.insert(settings).values({
      key: 'product_categories',
      value: valueStr,
      description: '产品一级分类列表'
    });
  } else {
    await db.update(settings)
      .set({
        value: valueStr
      })
      .where(eq(settings.key, 'product_categories'));
  }
  
  Logger.info('Product categories updated', { count: categories.length });
  return successResponse(null, '产品分类更新成功');
});

/**
 * 获取案例标签
 */
export const getCaseTags = asyncHandler(async ({ }: Context) => {
  const setting = await db.select()
    .from(settings)
    .where(eq(settings.key, 'case_tags'))
    .limit(1);
  
  let tags = [];
  if (setting.length > 0) {
    try {
      tags = JSON.parse(setting[0]?.value || '[]');
    } catch {
      tags = [];
    }
  }
  
  Logger.info('Case tags retrieved', { count: tags.length });
  return successResponse(tags);
});

/**
 * 更新案例标签
 */
export const updateCaseTags = asyncHandler(async ({ body, user }: Context) => {
  // 检查权限
  const accessCheck = checkReadOnlyAccess(user, 'PUT');
  if (!accessCheck.allowed) {
    throw ApiError.forbidden(accessCheck.message);
  }
  const { tags } = body as { tags: string[] };
  
  if (!Array.isArray(tags)) {
    throw ApiError.validation('标签必须是数组格式');
  }
  
  const valueStr = JSON.stringify(tags);
  
  // 检查设置是否存在
  const existingSetting = await db.select()
    .from(settings)
    .where(eq(settings.key, 'case_tags'))
    .limit(1);
  
  if (existingSetting.length === 0) {
    await db.insert(settings).values({
      key: 'case_tags',
      value: valueStr,
      description: '案例标签列表'
    });
  } else {
    await db.update(settings)
      .set({
        value: valueStr
      })
      .where(eq(settings.key, 'case_tags'));
  }
  
  Logger.info('Case tags updated', { count: tags.length });
  return successResponse(null, '案例标签更新成功');
});

/**
 * 获取案例分类（一级分类）
 */
export const getCaseCategories = asyncHandler(async ({ }: Context) => {
  const setting = await db.select()
    .from(settings)
    .where(eq(settings.key, 'case_categories'))
    .limit(1);
  
  let categories = [];
  if (setting.length > 0) {
    try {
      categories = JSON.parse(setting[0]?.value || '[]');
    } catch {
      categories = [];
    }
  }
  
  // 如果没有数据，返回默认分类
  if (categories.length === 0) {
    categories = ['教育培训', '医疗健康', '商业零售', '政府机关', '工业制造'];
  }
  
  Logger.info('Case categories retrieved', { count: categories.length });
  return successResponse(categories);
});

/**
 * 更新案例分类（一级分类）
 */
export const updateCaseCategories = asyncHandler(async ({ body, user }: Context) => {
  // 检查权限
  const accessCheck = checkReadOnlyAccess(user, 'PUT');
  if (!accessCheck.allowed) {
    throw ApiError.forbidden(accessCheck.message);
  }
  const { categories } = body as { categories: string[] };
  
  if (!Array.isArray(categories)) {
    throw ApiError.validation('分类必须是数组格式');
  }
  
  // 验证分类名称
  for (const category of categories) {
    if (typeof category !== 'string' || !category.trim()) {
      throw ApiError.validation('分类名称必须是非空字符串');
    }
  }
  
  const valueStr = JSON.stringify(categories);
  
  // 检查设置是否存在
  const existingSetting = await db.select()
    .from(settings)
    .where(eq(settings.key, 'case_categories'))
    .limit(1);
  
  if (existingSetting.length === 0) {
    await db.insert(settings).values({
      key: 'case_categories',
      value: valueStr,
      description: '案例一级分类列表'
    });
  } else {
    await db.update(settings)
      .set({
        value: valueStr
      })
      .where(eq(settings.key, 'case_categories'));
  }
  
  Logger.info('Case categories updated', { count: categories.length });
  return successResponse(null, '案例分类更新成功');
});

/**
 * 删除设置
 */
export const deleteSetting = asyncHandler(async ({ params, user }: Context) => {
  // 检查权限
  const accessCheck = checkReadOnlyAccess(user, 'DELETE');
  if (!accessCheck.allowed) {
    throw ApiError.forbidden(accessCheck.message);
  }
  const { key } = params as { key: string };
  
  if (!key) {
    throw ApiError.validation('设置键不能为空');
  }
  
  const result = await db.delete(settings)
    .where(eq(settings.key, key));
  
  Logger.info('Setting deleted', { key });
  return successResponse(null, '设置删除成功');
});

/**
 * 初始化默认设置
 */
export const initializeDefaultSettings = async () => {
  try {
    const defaultSettings = [
      {
        key: 'contact_modal',
        value: JSON.stringify({
          title: '联系我们',
          subtitle: `工作时间：${process.env.BUSINESS_HOURS || '周一至周五 9:00-18:00'} | 我们会在24小时内回复您的咨询`,
          contacts: [
            {
              name: '客服专员',
              position: '业务咨询',
              phone: process.env.CONTACT_PHONE || '153-0760-9741',
              wechat: '',
              avatar: '',
              description: '负责业务咨询和方案设计'
            }
          ]
        }),
        description: '联系人模态框配置'
      }
    ];
    
    // 检查并插入默认设置
    for (const defaultSetting of defaultSettings) {
      const existing = await db.select()
        .from(settings)
        .where(eq(settings.key, defaultSetting.key))
        .limit(1);
      
      if (existing.length === 0) {
        await db.insert(settings).values({
          ...defaultSetting
        });
      }
    }
    
    Logger.info('Default settings initialized successfully');
  } catch (error) {
    Logger.error('Initialize default settings error:', error);
  }
};

/**
 * 数据备份
 */
export const createBackup = asyncHandler(async ({ user }: Context) => {
  // 检查权限
  const accessCheck = checkReadOnlyAccess(user, 'POST');
  if (!accessCheck.allowed) {
    throw ApiError.forbidden(accessCheck.message);
  }
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
  const backupDir = path.join(process.cwd(), 'backups');
  
  // 确保备份目录存在
  await fs.mkdir(backupDir, { recursive: true });
  
  // 获取数据库文件路径
  const dbPath = path.join(process.cwd(), 'database.sqlite');
  
  // 复制数据库文件作为备份
  const backupDbFile = path.join(backupDir, `database-${timestamp}.sqlite`);
  await fs.copyFile(dbPath, backupDbFile);
  
  const stats = await fs.stat(backupDbFile);
  
  Logger.info('Database backup created', { backupFile: backupDbFile, size: stats.size });
  return successResponse({
    backupFile: backupDbFile,
    timestamp,
    size: stats.size
  }, '数据备份创建成功');
});

/**
 * 获取备份列表
 */
export const getBackups = asyncHandler(async ({ }: Context) => {
  const backupDir = path.join(process.cwd(), 'backups');
  
  try {
    const files = await fs.readdir(backupDir);
    const backups = [];
    
    for (const file of files) {
      if (file.endsWith('.sqlite')) {
        const filePath = path.join(backupDir, file);
        const stats = await fs.stat(filePath);
        
        backups.push({
          id: file.replace('.sqlite', ''), // 使用文件名作为ID
          filename: file,
          size: stats.size,
          createdAt: stats.birthtime.toISOString(),
          path: filePath,
          status: 'success', // 文件存在即为成功状态
          type: 'manual' // 默认为手动备份
        });
      }
    }
    
    // 按创建时间倒序排列
    backups.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
    
    Logger.info('Backups retrieved', { count: backups.length });
    return successResponse(backups);
  } catch (dirError) {
    // 备份目录不存在
    Logger.info('Backup directory not found, returning empty list');
    return successResponse([]);
  }
});

/**
 * 下载备份
 */
export const downloadBackup = asyncHandler(async ({ params, set }: Context) => {
  const { filename } = params as { filename: string };
  
  if (!filename) {
    throw ApiError.validation('文件名不能为空');
  }
  
  const backupDir = path.join(process.cwd(), 'backups');
  const backupFile = path.join(backupDir, filename);
  
  // 安全检查：确保文件在备份目录内
  if (!backupFile.startsWith(backupDir)) {
    throw ApiError.validation('无效的备份文件路径');
  }
  
  // 检查文件是否存在
  try {
    await fs.access(backupFile);
  } catch {
    throw ApiError.notFound('备份文件不存在');
  }
  
  // 读取文件内容
  const fileContent = await fs.readFile(backupFile);
  
  set.headers = {
    'Content-Type': 'application/octet-stream',
    'Content-Disposition': `attachment; filename="${filename}"`
  };
  
  Logger.info('Backup file downloaded', { filename });
  return fileContent;
});

/**
 * 删除备份
 */
export const deleteBackup = asyncHandler(async ({ params, user }: Context) => {
  // 检查权限
  const accessCheck = checkReadOnlyAccess(user, 'DELETE');
  if (!accessCheck.allowed) {
    throw ApiError.forbidden(accessCheck.message);
  }
  const { filename } = params as { filename: string };
  
  if (!filename) {
    throw ApiError.validation('文件名不能为空');
  }
  
  const backupDir = path.join(process.cwd(), 'backups');
  const backupFile = path.join(backupDir, filename);
  
  // 安全检查：确保文件在备份目录内
  if (!backupFile.startsWith(backupDir)) {
    throw ApiError.validation('无效的备份文件路径');
  }
  
  await fs.unlink(backupFile);
  
  Logger.info('Backup file deleted', { filename });
  return successResponse(null, '备份文件删除成功');
});

/**
 * 恢复备份
 */
export const restoreBackup = asyncHandler(async ({ params, user }: Context) => {
  // 检查权限
  const accessCheck = checkReadOnlyAccess(user, 'POST');
  if (!accessCheck.allowed) {
    throw ApiError.forbidden(accessCheck.message);
  }
  const { filename } = params as { filename: string };
  
  if (!filename) {
    throw ApiError.validation('文件名不能为空');
  }
  
  const backupDir = path.join(process.cwd(), 'backups');
  const backupFile = path.join(backupDir, filename);
  const dbPath = path.join(process.cwd(), 'database.sqlite');
  
  // 安全检查
  if (!backupFile.startsWith(backupDir)) {
    throw ApiError.validation('无效的备份文件路径');
  }
  
  // 检查备份文件是否存在
  try {
    await fs.access(backupFile);
  } catch {
    throw ApiError.notFound('备份文件不存在');
  }
  
  // 创建当前数据库的备份
  const currentBackup = path.join(backupDir, `current-backup-${Date.now()}.sqlite`);
  await fs.copyFile(dbPath, currentBackup);
  
  // 恢复备份
  await fs.copyFile(backupFile, dbPath);
  
  Logger.info('Database restored from backup', { filename, currentBackup: path.basename(currentBackup) });
  return successResponse({
    restoredFrom: filename,
    currentBackup: path.basename(currentBackup)
  }, '数据恢复成功');
});